package com.itextpdf.text.pdf.mc;
import com.itextpdf.testutils.CompareTool;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.parser.*;
import com.itextpdf.text.xml.XMLUtil;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class AcroFieldsFlattenTest {
public static final String OUT_FOLDER = "./target/com/itextpdf/text/pdf/mc/";
public static final String CMP_FOLDER = "./src/test/resources/com/itextpdf/text/pdf/mc/";
@Before
public void init() {
File dir = new File(OUT_FOLDER);
if (dir.exists()) {
deleteDirectory(dir);
}
dir.mkdirs();
}
private void deleteDirectory(File path) {
if (path == null)
return;
if (path.exists()) {
for (File f : path.listFiles()) {
if (f.isDirectory()) {
deleteDirectory(f);
f.delete();
} else {
f.delete();
}
}
path.delete();
}
}
@Test
public void fieldFieldsAndFlattenTest() throws IOException, DocumentException, ParserConfigurationException, SAXException, InterruptedException {
String acroFormFileName = "SF2809.pdf";
String filledAcroFormFileName = "SF2809_filled.pdf";
String flattenAcroFormFileName = "SF2809_alt.pdf";
PdfReader reader = new PdfReader(CMP_FOLDER + acroFormFileName);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(OUT_FOLDER + filledAcroFormFileName));
AcroFields form = stamper.getAcroFields();
for (String key : form.getFields().keySet()) {
form.setField(key, key);
}
stamper.close();
LoggerFactory.getInstance().setLogger(new SysoLogger());
reader = new PdfReader(OUT_FOLDER + filledAcroFormFileName);
MCFieldFlattener flattener = new MCFieldFlattener();
flattener.process(reader, new FileOutputStream(OUT_FOLDER + flattenAcroFormFileName));
//compare(OUT_FOLDER + flattenAcroFormFileName, CMP_FOLDER + flattenAcroFormFileName);
}
private void compare(String outPdf, String cmpPdf) throws IOException, ParserConfigurationException, SAXException, InterruptedException, DocumentException {
CompareTool ct = new CompareTool();
Assert.assertNull(ct.compare(outPdf, cmpPdf, OUT_FOLDER, "difference"));
String outXml = new File(outPdf).getName();
String cmpXml = new File(cmpPdf).getName();
outXml = OUT_FOLDER + outXml.replaceAll(".pdf", "") + ".xml";
cmpXml = OUT_FOLDER + "cmp_" + cmpXml.replaceAll("cmp_", "").replaceAll(".pdf", "") + ".xml";
PdfReader reader = new PdfReader(outPdf);
FileOutputStream xmlOut = new FileOutputStream(outXml);
new MyTaggedPdfReaderTool().convertToXml(reader, xmlOut);
reader = new PdfReader(cmpPdf);
xmlOut = new FileOutputStream(cmpXml);
new MyTaggedPdfReaderTool().convertToXml(reader, xmlOut);
Assert.assertTrue(compareXmls(outXml, cmpXml));
}
private boolean compareXmls(String xml1, String xml2) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setCoalescing(true);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setIgnoringComments(true);
DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document doc1 = db.parse(new File(xml1));
doc1.normalizeDocument();
org.w3c.dom.Document doc2 = db.parse(new File(xml2));
doc2.normalizeDocument();
return doc2.isEqualNode(doc1);
}
static class MyTaggedPdfReaderTool extends TaggedPdfReaderTool {
@Override
public void parseTag(String tag, PdfObject object, PdfDictionary page)
throws IOException {
if (object instanceof PdfNumber) {
PdfNumber mcid = (PdfNumber) object;
RenderFilter filter = new MyMarkedContentRenderFilter(mcid.intValue());
TextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
FilteredTextRenderListener listener = new FilteredTextRenderListener(
strategy, filter);
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(
listener);
processor.processContent(PdfReader.getPageContent(page), page
.getAsDict(PdfName.RESOURCES));
out.print(XMLUtil.escapeXML(listener.getResultantText(), true));
} else {
super.parseTag(tag, object, page);
}
}
@Override
public void inspectChildDictionary(PdfDictionary k) throws IOException {
inspectChildDictionary(k, true);
}
}
static class MyMarkedContentRenderFilter extends MarkedContentRenderFilter {
int mcid;
public MyMarkedContentRenderFilter(int mcid) {
super(mcid);
this.mcid = mcid;
}
@Override
public boolean allowText(TextRenderInfo renderInfo){
return renderInfo.hasMcid(mcid, true);
}
}
}